package entity;

/**
 * 
 * A moving object is a moving query. At the same time, the focal object can be 
 * result of other moving queries. <br>  
 * 
 * 1.20 update the fullcells and partialCells to be alert region 
 * @author xiaohui
 */
import geometry.Circle;

import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.HashSet;

public class MovingObject {
	public int oid;
	// =====full cells and partial cells form the alert region===
	// public HashSet<Cell> fullCells;
	// public HashSet<Cell> partialCells;

	// ==================
	public boolean hasFriend;
	public boolean probe;
	// public AlertRegion alertRegion;
	public MobileRegion mRegion;

	// object satisfies
	public Point2D nextP;
	// public double speed;
	public Velocity velocity;

	// CellID registeredCell;

	// HashMap<Integer, Boolean> monitoringQueries;
	//
	// ArrayList<Query> ownQueries;

	// public MovingObject(int ID, Point loc, Speed spd, int timeStamp,
	// CellID cid, Field field) {
	// this.oid = ID;
	// this.p = loc;
	// this.v = spd;
	// this.ts = timeStamp;
	// this.registeredCell = cid;
	// this.ownQueries = new ArrayList<Query>();
	// this.monitoringQueries = new HashMap<Integer, Boolean>();
	// this.field = field;
	// }
	static int initResultCapacity = 64;
	public Point2D currLoc;

	public MovingObject(int ID, Point2D currLoc) {
		this.currLoc = currLoc;
		this.oid = ID;
		// this.speed = speed;
		this.nextP = null;
		// this.ownQueries = new ArrayList<Query>();
		// this.monitoringQueries = new HashMap<Integer, Boolean>();
		// fullCells = new HashSet<Cell>();
		// this.partialCells = new HashSet<Cell>();

		hasFriend = false;
		probe = false;
		// queryMonitorList = new HashSet<Integer>();
		// canMonitorList = new HashSet<Integer>();
	}

	// public void addFullCells(Cell c) {
	// fullCells.add(c);
	// }

	/**
	 * partial cells and canMonitorList are updated.
	 * 
	 * @param c
	 */
	// public void addPartCells(Cell c) {
	// partialCells.add(c);
	//
	// }

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.awt.geom.Ellipse2D#equals(java.lang.Object) To ensure the
	 * uniquness in the set.
	 */
	@Override
	public boolean equals(Object obj) {
		if (obj instanceof MovingObject) {
			return this.oid == ((MovingObject) obj).oid;
		}
		return false;
	}

	/**
	 * 
	 * @param anotherMo
	 * @return the distance between this center point with the center point of
	 *         anotherMo
	 */
	public double getDistance(MovingObject anotherMo) {
		return this.currLoc.distance(anotherMo.currLoc);
	}

	// /**
	// *
	// * @param anotherMo
	// * @return est. relative absolute speed between this mo and anotherMo
	// */
	// public double getRelativeSpeed(MovingObject anotherMo) {
	// return Math.abs(this.speed - anotherMo.speed);
	// }

	public Velocity getVelocity() {
		return velocity;
	}

	/**
	 * add the mo id into current result
	 * 
	 * @param mo
	 */

	/**
	 * 
	 * @param anotherObject
	 * @return true if anotherObject is inside this query circle
	 */

	// public void moveMonitorToResult(MovingObject mo){
	// // this.canMonitorList.remove(mo.oid);
	// this.currResult.add(mo.oid);
	// }

	// public void moveMonitorToQuery(MovingObject mo){
	// this.queryMonitorList.remove(mo.oid);
	// this.satisfiedQueries.add(mo.oid);
	// }

	// public void moveResultToMonitor(MovingObject mo) {
	// this.currResult.remove(mo.oid);
	// this.canMonitorList.add(mo.oid);
	// }

	// public void moveQueryToMoitor(MovingObject mo) {
	// this.satisfiedQueries.remove(mo.oid);
	// this.queryMonitorList.add(mo.oid);
	// }

	// public Msg_o2s_enterCell calCrossCellTime() {
	// assert (this.nextP != null) : "next location is not known";
	// Cell currentCell = this.field.CMatrix.getCell(this.registeredCell);
	// CellID cid = this.field.inWhichCell(this.nextP);
	// if (!this.registeredCell.equals(cid)) {
	// // test whether fly happens
	// assert (currentCell.neighboringCells.contains(cid)) :
	// "the object flies into a non-neighboring cell";
	// //todo: calculate event time
	// int fromObject = 0;
	// Msg_o2s_enterCell mec = new Msg_o2s_enterCell(this.ts + 1,
	// fromObject, this.oid, pre_cid, cid);
	// this.putMsgIntoMap((this.currentTS + 1), mec.toString());
	// this.handleEnterCell(mo.oid, pre_cid, cid);
	// }
	// }
	//
	// private double calCrossTime(){
	//
	// }

	public void printQueryResult() {
		System.out.println(this.toString());
		System.out.print("own query result:");
		// System.out.println(currResult);
	}

	// public void removeFullCell(Cell cell) {
	// fullCells.remove(cell);
	// }
	//
	// public void removePartCell(Cell cell) {
	// partialCells.remove(cell);
	// }
	//
	// public void removeMonitoringQuery(MovingObject movingQuery) {
	// if (this.satisfiedQueries.contains(movingQuery)) {
	// this.satisfiedQueries.remove(movingQuery);
	// }
	// }

	// public void setCenterP(Point2D point) {
	// super.setCenter(point);
	// }

	//
	// public void setAlertRegion(AlertRegion ar) {
	// this.alertRegion = ar;
	// }
	//	
	// public void setSafeRegion() {
	//		
	// }

	public String toString() {

		String s = "MO oid:" + this.oid + ", location:"
				+ this.currLoc.toString() + ", velocity:"
				+ this.velocity.toString();
		return s;
	}

	public double getCenterX() {
		return this.currLoc.getX();
	}

	public double getCenterY() {
		return this.currLoc.getY();
	}

	public Point2D getCenterP() {
		return this.currLoc;
	}

	public void setCenter(Point2D nextP2) {
		this.currLoc = nextP2;
	}
}
